package com.tuzhi.sys.service.impl;

import com.tuzhi.base.jpa.healper.QueryHelper;
import com.tuzhi.base.jpa.healper.wenhao.TPredicateBuilder;
import com.tuzhi.base.jpa.healper.wenhao.TSorts;
import com.tuzhi.base.jpa.healper.wenhao.TSpecifications;
import com.tuzhi.base.jpa.repository.BaseRepo;
import com.tuzhi.base.service.impl.AbsBaseService;
import com.tuzhi.sys.dto.SysMenuTreeDto;
import com.tuzhi.sys.jpa.entity.SysMenuEntity;
import com.tuzhi.sys.jpa.repository.SysMenuRepo;
import com.tuzhi.sys.service.SysMenuService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class SysMenuServiceImpl extends AbsBaseService<SysMenuEntity, Long> implements SysMenuService {

    private static final Logger log = LoggerFactory.getLogger(SysMenuServiceImpl.class);

    @Autowired
    SysMenuRepo repo;


    @Override
    protected BaseRepo getThisRepo() {
        return repo;
    }

    @Override
    public List<SysMenuEntity> loadAllSysMenu() {
        QueryHelper.Builder<SysMenuEntity> builder = new QueryHelper.Builder<>();
        builder.eq(SysMenuEntity::getSysStatus, 0);
        return repo.findAll(builder.build().getWhereConditionBO());
    }

    @Override
    public List<SysMenuTreeDto> loadAllMenuTree() {
        return loadMenuTreeById(0L);
    }

    @Override
    public List<SysMenuTreeDto> loadMenuTreeById(Long id) {
        TPredicateBuilder<SysMenuEntity> query = TSpecifications.and();
        query.eq(SysMenuEntity::getSysStatus, 0);
        if (id.intValue() == 0) {
            Specification<SysMenuEntity> specification1 = TSpecifications.<SysMenuEntity>or()
                    .eq(SysMenuEntity::getPid, 0)
                    .eq(SysMenuEntity::getPid, null).build();
            query.predicate(specification1);
        } else {
            query.eq(SysMenuEntity::getPid, id);
        }
        Sort sort = TSorts.builder()
                .desc(SysMenuEntity::getSortNum)
                .build();
        List<SysMenuEntity> menuEntities = repo.findAll(query.build(), sort);
        if (CollectionUtils.isNotEmpty(menuEntities)) {
            List<SysMenuTreeDto> menuTreeDtos = new ArrayList<>(menuEntities.size());
            for (SysMenuEntity menuEntity : menuEntities) {
                SysMenuTreeDto sysDicTreeDto = menuEntity.trans();
                menuTreeDtos.add(sysDicTreeDto);
                loadChildMenus(sysDicTreeDto);
            }
            return menuTreeDtos;
        }
        return new ArrayList<>();
    }

    @Override
    public SysMenuEntity findByPerms(String perms) {
        return repo.findByPerms(perms);
    }

    @Override
    public SysMenuEntity findByUrl(String url) {
        return repo.findByUrl(url);
    }

    @Override
    public List<String> loadAllPerms() {
        return repo.loadAllPerms();
    }

    @Override
    public List<String> loadAllUrls() {
        return repo.loadAllUrls();
    }

    public void loadChildMenus(SysMenuTreeDto sysMenuTreeDto) {
        List<SysMenuEntity> menuEntities = findChildMenus(sysMenuTreeDto);
        if (CollectionUtils.isNotEmpty(menuEntities)) {
            for (SysMenuEntity menuEntity : menuEntities) {
                SysMenuTreeDto dto = menuEntity.trans();
                sysMenuTreeDto.addChildMenu(dto);
                loadChildMenus(dto);
            }
        }
    }


    public List<SysMenuEntity> findChildMenus(SysMenuTreeDto sysMenuTreeDto) {
        TPredicateBuilder<SysMenuEntity> query = TSpecifications.and();
        query.eq(SysMenuEntity::getSysStatus, 0)
                .eq(SysMenuEntity::getPid, sysMenuTreeDto.getId());
        Sort sort = TSorts.builder()
                .desc(SysMenuEntity::getSortNum)
                .build();
        List<SysMenuEntity> menuEntities = repo.findAll(query.build(), sort);
        return menuEntities;
    }


}
